package org.example.aienglishapp.service.login;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import org.example.aienglishapp.properties.AliyunSmsProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.util.Random;

import lombok.extern.slf4j.Slf4j;

/**
 * @author xlj
 * @since 2024-10-1
 * @version 1.0
 */
@Slf4j
@Service
public class SmsService {

    @Autowired
    private AliyunSmsProperties aliyunSmsProperties;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 验证码Redis key的前缀。
     */
    private static final String VERIFICATION_CODE_KEY_PREFIX = "verification:code:";

    /**
     * 发送短信验证码。
     *
     * @param phoneNumber 接收短信的手机号码
     * @param code        验证码
     * @return 发送短信的响应结果
     * @throws ClientException 如果发送过程中发生错误
     */
    public SendSmsResponse sendSms(String phoneNumber, String code) throws ClientException {
        // 记录AccessKey ID和AccessKey Secret信息
        log.info("Using AccessKeyId: {}", aliyunSmsProperties.getAccessKeyId());
        log.info("Using AccessKeySecret: {}", aliyunSmsProperties.getAccessKeySecret());
        log.info("Using SignName: {}", aliyunSmsProperties.getSignName());
        log.info("Using TemplateCode: {}", aliyunSmsProperties.getTemplateCode());

        log.info("发送短信到 {} 验证码为 {}", phoneNumber, code);

        // 设置超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        // 创建DefaultAcsClient实例并初始化
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-hangzhou",
                aliyunSmsProperties.getAccessKeyId(),
                aliyunSmsProperties.getAccessKeySecret()
        );

        IAcsClient client = new DefaultAcsClient(profile);

        // 创建API请求并设置参数
        SendSmsRequest request = new SendSmsRequest();
        request.setPhoneNumbers(phoneNumber);
        request.setSignName(aliyunSmsProperties.getSignName());
        request.setTemplateCode(aliyunSmsProperties.getTemplateCode());
        request.setTemplateParam("{\"code\":\"" + code + "\"}");

        // 发起请求并处理应答或异常
        return client.getAcsResponse(request);
    }

    /**
     * 生成六位数的随机验证码。
     *
     * @return 随机生成的六位数验证码
     */
    public String generateVerificationCode() {
        Random random = new Random();
        return String.format("%06d", random.nextInt(999999));
    }

    /**
     * 将验证码存储在Redis中。
     *
     * @param phoneNumber          手机号码
     * @param verificationCode     验证码
     */
    @Transactional
    public void storeVerificationCode(String phoneNumber, String verificationCode) {
        String key = VERIFICATION_CODE_KEY_PREFIX + phoneNumber;
        redisTemplate.opsForValue().set(key, verificationCode, Duration.ofHours(12));
    }

    /**
     * 验证用户输入的验证码是否正确。
     *
     * @param phoneNumber          手机号码
     * @param verificationCode     用户提供的验证码
     * @return 如果验证码匹配则返回true，否则返回false
     */
    public boolean validateVerificationCode(String phoneNumber, String verificationCode) {
        String key = VERIFICATION_CODE_KEY_PREFIX + phoneNumber;
        String storedCode = redisTemplate.opsForValue().get(key);
        if (storedCode != null && storedCode.equals(verificationCode)) {
            // 验证码有效
            log.info("验证码验证成功，手机号: {}", phoneNumber);
            return true;
        } else {
            // 验证码无效或已过期
            log.warn("验证码验证失败，手机号: {}", phoneNumber);
            return false;
        }
    }
}